package com.sojson.util.mq.rabbit.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.stereotype.Component;

import com.sojson.aspect.PointcutsBase;
import com.sojson.util.StringUtil;
import com.sojson.util.log.LogUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * Rabbit操作日志记录处理
 * 
 * @author liu
 * @date 2022-06-25
 */
@Slf4j
@Aspect
@Component
public class RabbitLogAspect implements PointcutsBase {

    /** 配置织入点 */
    @Pointcut("@annotation(org.springframework.amqp.rabbit.annotation.RabbitHandler)")
    public void logPointCut() {}

    /**
     * 请求处理之前
     * 
     * @param joinPoint 切点
     * @throws Throwable 
     */
    @Around("logPointCut()")
    public Object doAfterReturning(ProceedingJoinPoint pjp) throws Throwable {
        Message msg = null;
        Object[] args = pjp.getArgs();
        for (Object obj : args) {
            if (obj instanceof Message) {
                msg = (Message)obj;
                break;
            }
        }

        Object proceed = null;
        try {
            if (StringUtil.isNotBlankObject(msg)) {
                // 设置
                MessageProperties pro = msg.getMessageProperties();
                String msgId = pro.getMessageId();
                if (StringUtil.isBlankString(msgId)) {
                    LogUtil.setTraceId();
                } else {
                    LogUtil.setTraceId(msgId);
                }
                log.info(StringUtil.ENTER + "Rabbit交换机: " + pro.getReceivedExchange() + ", 队列: "
                    + pro.getConsumerQueue() + ", 收到消息: " + new String(msg.getBody()));
            } else {
                LogUtil.setTraceId();
                log.info("Rabbit收到消息");
            }

            proceed = pjp.proceed();
        } finally {
            LogUtil.clearTraceId();
        }
        return proceed;
    }

}